/* 
 * Copyright (c) 2009, Giora Kosoi giorak@gmail.com
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the project nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY Giora Kosoi ''AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL Giora Kosoi BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef VARS_H
#define VARS_H

#include <sparrow/stable.h>
#include <sparrow/variant.h>
#include <sparrow/int_key.h>

class VariantSet : public Variant
{
    public:
        VariantSet();
        virtual ~VariantSet();

        Variant *get(const std::string &key) const;
        Variant *get(const std::string &key, const std::nothrow_t &) const;
        void set(const std::string &key, Variant *v);
        void remove(const std::string &key);

        Variant *get(const IntKey &key) const;
        Variant *get(const IntKey &key, const std::nothrow_t &) const;
        void set(const IntKey &key, Variant *v);
        void remove(const IntKey &key);

        Variant *get(size_t index, const std::nothrow_t &) const;
        Variant *get(size_t index) const;
        void set(size_t index, Variant *v);
        void insert(size_t index, Variant *v);
        void insert(Variant *v);
        void remove(size_t index);

        size_t array_size() const;
        size_t size() const;

        void clear();

        virtual Variant *clone() const;
        virtual const VariantSet *variant_set() const;
        virtual VariantSet *variant_set();
        virtual const std::string &pstr() const;

        Variant *release(const std::string &key);
        Variant *release(const IntKey &key);
        Variant *release(size_t index);

        Variant *release(const std::string &key, const std::nothrow_t &);
        Variant *release(const IntKey &key, const std::nothrow_t &);
        Variant *release(size_t index, const std::nothrow_t &);


    private:
        void add_pvar(const Variant *v) const;
        void remove_comma() const;
        void grow(size_t new_size);
        typedef std::vector<Variant *> var_vector;
        typedef std::map<std::string, Variant *> var_string_map;
        typedef std::map<IntKey, Variant *> var_int_map;
        var_string_map vsm;
        var_int_map vim;
        var_vector vv;
};

#endif // VARS_H

